#pragma once
#include "Common.hpp"
namespace ThreadPoolMudole
{
    template <typename T>
    class ThreadPool
    {
    private:
        void WakeUp()
        {
            LockGuard lock(_mutex);
            {
                if (_sleepernum > 0)
                    _cond.Broadcast();
            }
        }
        void WakeUpone()
        {
            LockGuard lockguard(_mutex);
            if (_sleepernum > 0)
                _cond.Signal();
        }

    public:
        ThreadPool(int num = 5) : _num(num), _isrunning(false), _sleepernum(0), _isdetach(false)
        {
            for (int i = 0; i < num; ++i)
            {
                _threads.emplace_back(HandlerTask());
            }
            LOG(LogLevel::INFO) << "create new ThreadPool" << num;
        }
        void Join()
        {
            for (auto &t : _threads)
            {
                t.Join();
            }
        }
        void Detch()
        {
            if (_isdetach)
                return;
            _isdetach = true;
            for (auto &t : _threads)
            {
                t.Detach();
            }
            LOG(LogLevel::INFO) << "this ThreadPool is detach";
        }
        void HandlerTask()
        {
            Enable_Console_Log;
            while (true)
            {
                T t;
                {
                    LockGuard lockguard(_mutex);

                    while (_taskq.empty() && _isrunning) // 只有运行中且队列空时才等待
                    {
                        _sleepernum++;
                        _cond.Wait(&_mutex);
                        _sleepernum--;

                        // 检查是否被Stop唤醒
                        if (!_isrunning)
                            break;
                    }

                    // 检查退出条件
                    if (!_isrunning && _taskq.empty())
                    {
                        LOG(LogLevel::INFO) << "Thread exiting";
                        break;
                    }

                    // 如果是因为有任务而被唤醒，处理任务
                    if (!_taskq.empty())
                    {
                        t = std::move(_taskq.front());
                        _taskq.pop();
                    }
                }

                // 执行任务（在锁外）
                if (t) // 确保任务有效
                {
                    try
                    {
                        t();
                    }
                    catch (const std::exception &e)
                    {
                        LOG(LogLevel::ERROR) << "Task execution failed: " << e.what();
                    }
                }
            }
        }
        ~ThreadPool() {}
        void Start()
        {
            if (_isrunning)
                return;
            _isrunning = true;
            for (auto &t : _threads)
            {
                t.Start();
            }
        }
        void Stop()
        {
            if (!_isrunning)
                return;
            _isrunning = false;
            // 通知所有线程
            WakeUp();
        }
        bool Enqueue(const T &t)
        {
            LockGuard lockguard(_mutex);
            if (!_isrunning)
            {
                LOG(LogLevel::ERROR) << "ThreadPool is not running";
                return false;
            }
            _taskq.push(t);
            WakeUpone();
            return true;
        }

    private:
        int _num;
        std::vector<Thread> _threads;
        std::queue<T> _taskq; // 任务队列
        Cond _cond;           // 条件变量
        Mutex _mutex;         // 互斥锁
        bool _isrunning;
        int _sleepernum; // 休眠者的数量
        int _isdetach;   // 是否分离
    };
}